package point_application

import (
	"gq_volunteer_platform/bean"
	"gq_volunteer_platform/model/activity"
	"gq_volunteer_platform/model/admin"
	"gq_volunteer_platform/model/point_application"
	"gq_volunteer_platform/model/user"
	"gq_volunteer_platform/service/message_queue"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
)

// 用户积分申请（时长补登）
// 超级管理员
func List(c *gin.Context) {

	var req struct {
		Page        int    `binding:"required,gte=1"`
		Limit       int    `binding:"required,gte=1"`
		CheckStatus string `binding:"oneof='' 待审核 已审核 已驳回"`
	}

	if err := c.ShouldBindQuery(&req); err != nil {
		bean.Log.Warning(err.Error())
		c.String(400, err.Error())
		return
	}

	var offset = (req.Page - 1) * req.Limit

	// 查询
	var count int64

	var list []struct {
		point_application.PointApplication
		ActivityName string
	}

	var tx = bean.MysqlDb.Model(&point_application.PointApplication{}).
		Select("`point_application`.*,`activity`.`name` as activity_name").
		Joins("LEFT JOIN `activity` on `activity`.`id` = `point_application`.`activity_id`")

	if req.CheckStatus != "" {
		tx = tx.Where("`check_status`=?", req.CheckStatus)
	}

	// 查询总数
	if err := tx.Count(&count).Error; err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	// 查询列表
	if err := tx.Limit(req.Limit).Offset(offset).Order("`id` DESC").Find(&list).Error; err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	c.PureJSON(200, gin.H{
		"count": count,
		"list":  list,
	})
}

// 用户积分申请（时长补登）
// 我提交的申请
func MyList(c *gin.Context) {
	// 管理员信息
	var adm admin.Admin
	if err := adm.Get(c); err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	var req struct {
		Page        int    `binding:"required,gte=1"`
		Limit       int    `binding:"required,gte=1"`
		CheckStatus string `binding:"oneof='' 待审核 已审核 已驳回"`
	}

	if err := c.ShouldBindQuery(&req); err != nil {
		bean.Log.Warning(err.Error())
		c.String(400, err.Error())
		return
	}

	var offset = (req.Page - 1) * req.Limit

	// 查询
	var count int64
	var list []struct {
		point_application.PointApplication
		ActivityName string
	}

	var tx = bean.MysqlDb.Model(&point_application.PointApplication{}).
		Select("`point_application`.*,`activity`.`name` as activity_name").
		Joins("LEFT JOIN `activity` on `activity`.`id` = `point_application`.`activity_id`")

	if req.CheckStatus != "" {
		tx = tx.Where("`check_status`=?", req.CheckStatus)
	}

	tx.Where("`point_application`.`organization_id`=?", adm.OrganizationId)

	// 查询总数
	if err := tx.Count(&count).Error; err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	// 查询列表
	if err := tx.Limit(req.Limit).Offset(offset).Order("`id` DESC").Find(&list).Error; err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	c.PureJSON(200, gin.H{
		"count": count,
		"list":  list,
	})
}

// 积分申请-查看详情（时长补登）
func Detail(c *gin.Context) {
	var req struct {
		ID int `binding:"max=10000000"`
	}

	if err := c.ShouldBindQuery(&req); err != nil {
		bean.Log.Warning(err.Error())
		c.String(400, err.Error())
		return
	}

	var one point_application.PointApplication
	if err := bean.MysqlDb.Where("`id`=?", req.ID).First(&one).Error; err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	var list []struct {
		ID       uint
		UserId   uint
		UserName string
		Point    int
	}

	// 查询列表
	if err := bean.MysqlDb.Model(&point_application.PointApplicationUser{}).
		Select("`point_application_user`.`id` as id,`point_application_user`.`user_id`,`user`.`name` as user_name,`point_application_user`.`point`").
		Joins("LEFT JOIN `user` on `user`.`id` = `point_application_user`.`user_id`").
		Where("`point_application_id`=?", req.ID).Find(&list).Error; err != nil {

		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	c.PureJSON(200, gin.H{
		"detail":    one,
		"user_list": list,
	})
}

// 积分申请（时长补登）
func Apply(c *gin.Context) {

	// 管理员信息
	var adm admin.Admin
	if err := adm.Get(c); err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	// 请求信息
	var req struct {
		Reason     string `binding:"max=255"`
		ActivityId uint   `binding:"max=10000000"`
		Users      []struct {
			UserId uint `binding:"max=10000000"`
			Point  uint `binding:"max=10000000"`
		}
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		bean.Log.Warning(err)
		c.String(400, err.Error())
		return
	}

	var act activity.Activity
	if err := bean.MysqlDb.Where("`id`=?", req.ActivityId).First(&act).Error; err != nil {
		bean.Log.Error(err)
		c.String(400, err.Error())
		return
	}

	var one point_application.PointApplication

	one.CheckStatus = "待审核"
	one.OrganizationId = adm.OrganizationId
	one.ActivityId = req.ActivityId
	one.Reason = req.Reason

	var tx = bean.MysqlDb.Begin()

	if err := tx.Create(&one).Error; err != nil {
		tx.Rollback()
		bean.Log.Error(err)
		c.String(500, "数据库错误")
		return
	}

	for _, v := range req.Users {
		// 分数为零，则跳过
		if v.Point == 0 {
			continue
		}

		// 检测用户是否存在
		var u user.User
		if err := tx.Where("`id`=?", v.UserId).First(&u).Error; err != nil {
			tx.Rollback()
			bean.Log.Error(err)
			c.String(400, err.Error())
			return
		}

		var two point_application.PointApplicationUser
		two.PointApplicationId = one.ID
		two.Point = int(v.Point)
		two.UserId = v.UserId
		if err := tx.Create(&two).Error; err != nil {
			tx.Rollback()
			bean.Log.Error(err)
			c.String(500, "数据库错误")
			return
		}
	}

	// 提交执行
	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	c.String(200, "ok")

}

// 积分申请-审核（时长补登）
func Check(c *gin.Context) {

	// 请求信息
	var req struct {
		ID          uint   `binding:"max=10000000"`
		CheckStatus string `binding:"oneof=已审核 已驳回"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		bean.Log.Warning(err)
		c.String(400, err.Error())
		return
	}

	// 查询记录
	var one point_application.PointApplication
	if err := bean.MysqlDb.Where("`id`=?", req.ID).First(&one).Error; err != nil {
		bean.Log.Error(err)
		c.String(400, err.Error())
		return
	}

	// 状态相同跳过
	if one.CheckStatus == req.CheckStatus {
		c.String(200, "ok")
		return
	}

	// 申请的组织名称
	// var organizationName, err = organization.IdGetName(one.OrganizationId)
	// if err != nil {
	// 	bean.Log.Error(err)
	// 	c.String(500, err.Error())
	// 	return
	// }

	// 修改审核状态
	var two point_application.PointApplication
	two.ID = one.ID
	two.CheckStatus = req.CheckStatus

	var tx = bean.MysqlDb.Begin()

	if err := tx.Updates(&two).Error; err != nil {
		tx.Rollback()

		bean.Log.Error(err)
		c.String(500, "数据库错误")
		return
	}

	// 审核通过
	if req.CheckStatus == "已审核" {
		var activity_list activity.Activity
		if err := bean.MysqlDb.Where("`id`=?", one.ActivityId).First(&activity_list).Error; err != nil {
			bean.Log.Error(err)
			c.String(400, err.Error())
			return
		}

		var userList []point_application.PointApplicationUser
		if err := bean.MysqlDb.Where("`point_application_id`=?", req.ID).Find(&userList).Error; err != nil {
			tx.Rollback()

			bean.Log.Error(err)
			c.String(500, err.Error())
			return
		}

		for _, v := range userList {
			if err := user.AddPoint(tx, v.UserId, v.Point, "积分补登："+activity_list.Name); err != nil {
				tx.Rollback()
				bean.Log.Error(err)
				c.String(500, err.Error())
				return
			}
			// 发送通知 jldtx
			var user_list struct {
				ID     uint
				Openid string
			}
			if err := bean.MysqlDb.Unscoped().Model(&user.User{}).Where("`id`=?", v.UserId).First(&user_list).Error; err != nil {
				bean.Log.Error(err)
				// return
			}
			var timeNowStr = time.Now().Format(time.DateTime)

			var Openid = user_list.Openid
			var page = "pages/index/index"
			var applyProject = "“" + activity_list.Name + "”时长补登"
			var applyTime = timeNowStr
			// var applyResult = activity_list.Name + "时长补登" + strconv.Itoa(v.Point) + "工时已通过"
			var applyResult = "时长补登：" + strconv.Itoa(v.Point) + "工时已通过"
			if err := message_queue.MessageQueueAddT1(Openid, page, applyProject, applyTime, applyResult); err != nil {
				// 错误记录
				bean.Log.Error(err)
			}
		}
	}

	// 提交执行
	if err := tx.Commit().Error; err != nil {
		tx.Rollback()

		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	c.String(200, "ok")
}

// 积分申请-删除（时长补登）
func Delete(c *gin.Context) {

	// 请求信息
	var req struct {
		ID uint `binding:"max=10000000"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		bean.Log.Warning(err)
		c.String(400, err.Error())
		return
	}

	// 查询记录
	var one point_application.PointApplication
	if err := bean.MysqlDb.Where("`id`=?", req.ID).First(&one).Error; err != nil {
		bean.Log.Error(err)
		c.String(400, err.Error())
		return
	}

	if one.CheckStatus != "待审核" {
		c.String(400, "该状态申请单不可删除checkStatus："+one.CheckStatus)
		return
	}

	if err := bean.MysqlDb.Delete(&one).Error; err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	c.String(200, "ok")
}
